﻿using Microsoft.AspNetCore.SignalR;
using UAParser;

namespace Magic.System;

public class ChatHub : Hub<IChatHub>
{
    private readonly SugarRepository<SysUserOnline> _onlineUserRep;
    private IHubContext<ChatHub, IChatHub> _chatHub;
    private readonly IJWTBuilder _jwtBuilder;

    public ChatHub(SugarRepository<SysUserOnline> onlineUserRep,
                   IHubContext<ChatHub, IChatHub> chatHub,
                   IJWTBuilder jwtBuilder)
    {
        _onlineUserRep = onlineUserRep;
        _chatHub = chatHub;
        _jwtBuilder = jwtBuilder;
    }
    /// <summary>
    /// 连接
    /// </summary>
    /// <returns></returns>
    public override async Task OnConnectedAsync()
    {
        var token = Context.GetHttpContext().Request.Query["access_token"];
        var claims = _jwtBuilder.ReadJwtToken(token)?.Claims;
        var client = Parser.GetDefault().Parse(Context.GetHttpContext().Request.Headers["User-Agent"]);
        var userId = claims.FirstOrDefault(u => u.Type == ClaimConst.UserId)?.Value;
        var ip = App.HttpContext.Connection.RemoteIpAddress?.MapToIPv4()?.ToString();
        if (await _onlineUserRep.IsAnyAsync(p => p.UserId == userId && p.Ip == ip))
            await _onlineUserRep.DeleteAsync(p => p.UserId == userId && p.Ip == ip);
        var user = new SysUserOnline
        {
            ConnectionId = Context.ConnectionId,
            UserId = string.IsNullOrWhiteSpace(userId) ? "0" : userId,
            UserName = claims.FirstOrDefault(u => u.Type == ClaimConst.UserName)?.Value,
            NickName = claims.FirstOrDefault(u => u.Type == ClaimConst.NickName)?.Value,
            Time = DateTime.Now,
            Ip = ip,
            Browser = client.UA.Family + client.UA.Major,
            Os = client.OS.Family + client.OS.Major,
        };
        await _onlineUserRep.InsertAsync(user);
    }
    /// <summary>
    /// 断开连接
    /// </summary>
    /// <param name="exception"></param>
    /// <returns></returns>
    public override async Task OnDisconnectedAsync(Exception exception)
    {
        if (string.IsNullOrEmpty(Context.ConnectionId)) return;
        var user = await _onlineUserRep.AsQueryable().FirstAsync(u => u.ConnectionId == Context.ConnectionId);
        if (user == null) return;
        await _onlineUserRep.DeleteAsync(p => p.UserId == user.UserId);
    }
}
